from PySide6.QtWidgets import (QGraphicsScene, QGraphicsView, QVBoxLayout, 
                             QWidget, QHBoxLayout, QFileDialog, QApplication)
from PySide6.QtCore import Qt, QRectF, QPointF, QProcess, QTimer, QBuffer, QByteArray, QPoint
from PySide6.QtGui import (QPixmap, QPen, QColor, QPainterPath, QUndoStack, 
                          QUndoCommand, QPainter, QIcon, QTransform)
from qfluentwidgets import (PushButton, SubtitleLabel,PrimaryPushButton,
                           FluentIcon as FIF, CheckBox)
from qfluentwidgetspro import ToolTipSlider
from app.common.config import cfg  # 导入配置
import sys
import ctypes
from app.common.global_vars import g_vars
import keyboard
import win32clipboard
from io import BytesIO
import win32con
# 添加撤销命令类
class AddRectCommand(QUndoCommand):
    def __init__(self, scene, rect_item):
        super().__init__()
        self.scene = scene
        self.rect_item = rect_item
        self.rect_geom = rect_item.rect()  # 保存矩形的几何信息
        
    def undo(self):
        if self.rect_item in self.scene.rect_items:
            idx = self.scene.rect_items.index(self.rect_item)
            self.scene.rect_items.remove(self.rect_item)
            self.scene.rectangles.pop(idx)
            self.scene.removeItem(self.rect_item)
            self.scene._update_merged_path()
        
    def redo(self):
        if self.rect_item not in self.scene.rect_items:
            self.scene.rect_items.append(self.rect_item)
            self.scene.rectangles.append(self.rect_geom)
            self.scene.addItem(self.rect_item)
            self.scene._update_merged_path()

class SelectableGraphicsScene(QGraphicsScene):
    def __init__(self, parent=None):
        super().__init__(parent)
        self.drawing = False
        self.start_pos = None
        self.current_rect = None
        self.rectangles = []  # 储矩形的几何信息
        self.rect_items = []  # 存储矩形项
        self.merged_path = QPainterPath()
        self.undo_stack = QUndoStack(self)
        self.undo_stacks = []  # 存储历史状态
        self.redo_stacks = []  # 存储重做状态
        self.has_image = False  # 添加图片加载状态标志
        self.main_window = None  # 存储主窗口引用
        self.has_selection = False  # 添加标记来追踪是否有选区
        
    def set_main_window(self, window):
        """设置主窗口引用"""
        self.main_window = window
        
    def mousePressEvent(self, event):
        if event.button() == Qt.LeftButton and self.has_image:  # 有加载图片后才能绘制
            # 确保起始点在图片范围内
            image_rect = self.sceneRect()
            pos = event.scenePos()
            
            # 如果点击在图片外部，直接返回
            if not image_rect.contains(pos):
                return
                
            self.drawing = True
            self.start_pos = pos
            self.current_rect = self.addRect(
                QRectF(self.start_pos, self.start_pos),
                QPen(QColor(0, 120, 212), 2)  # 使用蓝色实线
            )
            
    def mouseMoveEvent(self, event):
        if self.drawing and self.current_rect and self.has_image:  # 确保有图片时才能移动
            pos = event.scenePos()
            
            # 获取图片边界
            image_rect = self.sceneRect()
            
            # 限制坐标在图片范围内
            pos.setX(min(max(pos.x(), image_rect.left()), image_rect.right()))
            pos.setY(min(max(pos.y(), image_rect.top()), image_rect.bottom()))
            
            # 同样限制起始点
            start_x = min(max(self.start_pos.x(), image_rect.left()), image_rect.right())
            start_y = min(max(self.start_pos.y(), image_rect.top()), image_rect.bottom())
            self.start_pos = QPointF(start_x, start_y)
            
            # 计算矩形
            rect = QRectF(
                min(self.start_pos.x(), pos.x()),
                min(self.start_pos.y(), pos.y()),
                abs(pos.x() - self.start_pos.x()),
                abs(pos.y() - self.start_pos.y())
            )
            
            # 确保矩形不超出图片边界
            if rect.right() > image_rect.right():
                rect.setRight(image_rect.right())
            if rect.bottom() > image_rect.bottom():
                rect.setBottom(image_rect.bottom())
            if rect.left() < image_rect.left():
                rect.setLeft(image_rect.left())
            if rect.top() < image_rect.top():
                rect.setTop(image_rect.top())
                
            self.current_rect.setRect(rect)
            
    def mouseReleaseEvent(self, event):
        if event.button() == Qt.LeftButton and self.drawing and self.has_image:  # 确保有图片时才能完成绘制
            self.drawing = False
            if self.current_rect:
                # 保存矩形的几何信息
                self.rectangles.append(self.current_rect.rect())
                self.rect_items.append(self.current_rect)
                # 保存当前状态到撤销栈
                self.undo_stacks.append([item.rect() for item in self.rect_items])
                # 清空重做栈
                self.redo_stacks.clear()
                # 更新撤销/重做按钮状
                self._update_undo_redo_state()
                self._update_merged_path()
                self.has_selection = True  # 有新的选区时设置标记
                if self.main_window:
                    self.main_window.update_confirm_button()  # 更新保存按钮状态
            self.current_rect = None
            
    def set_has_image(self, has_image):
        """设置是否已加载图片"""
        self.has_image = has_image
        if not has_image:
            self.clear_selection()  # 如果没有图片，除所有选择
        
    def _update_merged_path(self):
        # 创场景大小的路径
        self.merged_path = QPainterPath()
        self.merged_path.addRect(self.sceneRect())
        
        # 从场景路径中减去每个矩形
        for item in self.rect_items:
            rect_path = QPainterPath()
            rect_path.addRect(item.rect())
            item.setPen(Qt.NoPen)  # 隐藏原始矩的边框
            self.merged_path = self.merged_path.subtracted(rect_path)
        
        # 反转路径（与场景路径相减获得选中区域）
        reverse_path = QPainterPath()
        reverse_path.addRect(self.sceneRect())
        reverse_path = reverse_path.subtracted(self.merged_path)
        self.merged_path = reverse_path
        
        # 更新场
        self.update()
        
    def drawForeground(self, painter, rect):
        super().drawForeground(painter, rect)
        if not self.merged_path.isEmpty():
            pen = QPen(QColor(0, 120, 212), 2)  # 蓝色实线，宽度2
            painter.setPen(pen)
            painter.drawPath(self.merged_path)
            
    def undo(self):
        if len(self.undo_stacks) >= 2:
            # 保存当前状态到重做栈
            current_state = self.undo_stacks.pop()
            self.redo_stacks.append(current_state)
            # 复上一个状态
            previous_state = self.undo_stacks[-1]
            self._restore_state(previous_state)
        elif len(self.undo_stacks) == 1:
            # 如果只有一个状态，清空所有
            self.undo_stacks.clear()
            self.clear_selection()
        self._update_undo_redo_state()
            
    def redo(self):
        if self.redo_stacks:
            # 恢复重做状态
            next_state = self.redo_stacks.pop()
            self.undo_stacks.append(next_state)
            self._restore_state(next_state)
        self._update_undo_redo_state()
            
    def _restore_state(self, state):
        """复指定状态"""
        # 清除当前所有矩形
        for item in self.rect_items:
            self.removeItem(item)
        self.rect_items.clear()
        self.rectangles.clear()
        
        # 重新创建矩形
        for rect_geom in state:
            rect_item = self.addRect(
                rect_geom,
                QPen(QColor(0, 120, 212), 2)
            )
            self.rect_items.append(rect_item)
            self.rectangles.append(rect_geom)
            
        self._update_merged_path()
        
    def _update_undo_redo_state(self):
        """新撤销/重做按钮状态"""
        if self.main_window:
            self.main_window.undo_button.setEnabled(len(self.undo_stacks) > 0)
            self.main_window.redo_button.setEnabled(len(self.redo_stacks) > 0)
            
    def clear_selection(self):
        """清除所有选区"""
        # 先移除所有图形项
        for item in self.rect_items:
            if item.scene() == self:  # 检查item是否还在场景中
                self.removeItem(item)
        
        # 清空数据结构
        self.rectangles.clear()
        self.rect_items.clear()
        self.undo_stacks.clear()
        self.redo_stacks.clear()
        self.merged_path = QPainterPath()
        self.has_selection = False
        
        # 更新UI状态
        self._update_undo_redo_state()
        if self.main_window:
            self.main_window.update_confirm_button()
        self.update()

class CustomGraphicsView(QGraphicsView):
    def __init__(self, parent=None):
        super().__init__(parent)
        self.setRenderHint(QPainter.Antialiasing)
        self.setViewportUpdateMode(QGraphicsView.FullViewportUpdate)
        self.setHorizontalScrollBarPolicy(Qt.ScrollBarAsNeeded)
        self.setVerticalScrollBarPolicy(Qt.ScrollBarAsNeeded)
        self.setRenderHint(QPainter.SmoothPixmapTransform)
        self.setTransformationAnchor(QGraphicsView.NoAnchor)
        self.setResizeAnchor(QGraphicsView.NoAnchor)

    def wheelEvent(self, event):
        """处理鼠标滚轮事件"""
        # 检查是否按住Ctrl键
        if event.modifiers() == Qt.ControlModifier and self.scene():
            # 获取当前鼠标位置
            mouse_pos = event.position()
            
            # 保存鼠标位置对应的场景坐标
            scene_pos = self.mapToScene(QPoint(int(mouse_pos.x()), int(mouse_pos.y())))
            
            # 计算缩放因子
            zoom_factor = 1.1 if event.angleDelta().y() > 0 else 1.0 / 1.1
            
            # 获取当前缩放值并计算新的缩放值
            current_zoom = self.transform().m11() * 100
            new_zoom = max(10, min(400, current_zoom * zoom_factor))
            
            # 更新主窗口的缩放滑块
            if isinstance(self.parent(), ImageSelectorWindow):
                self.parent().zoom_slider.setValue(int(new_zoom))
            
            # 计算新的视图中心
            new_center = self.mapFromScene(scene_pos)
            center_delta = new_center - QPoint(int(mouse_pos.x()), int(mouse_pos.y()))
            self.centerOn(scene_pos)
            
            # 调整视图位置以保持鼠标位置不变
            viewport_center = self.viewport().rect().center()
            viewport_center -= center_delta
            self.centerOn(self.mapToScene(viewport_center))
            
            event.accept()
            return
            
        # 如果没有按Ctrl，使用默认的滚动行为
        super().wheelEvent(event)

class ImageSelectorWindow(QWidget):
    def __init__(self):
        super().__init__()
        self.current_pixmap = None
        self.initial_zoom = True
        self.controller = g_vars.video_note_controller
        self.setWindowTitle("图片区域选择器")
        # 使用保存的窗口尺寸
        self.resize(cfg.selectorWindowWidth.value, cfg.selectorWindowHeight.value)
        
        # 设置窗口图标
        self.setWindowIcon(QIcon(':/app/images/logo.png'))
        # 设置窗口置顶
        self.setWindowFlags(Qt.WindowStaysOnTopHint)
        # 创建布局
        self.layout = QVBoxLayout(self)
        self.layout.setContentsMargins(16, 16, 16, 16)
        
        # 创建场和视图
        self.scene = SelectableGraphicsScene()
        self.scene.set_main_window(self)
        self.view = CustomGraphicsView(self)
        self.view.setScene(self.scene)
        self.view.setRenderHint(QPainter.Antialiasing)
        self.view.setViewportUpdateMode(QGraphicsView.FullViewportUpdate)
        self.view.setHorizontalScrollBarPolicy(Qt.ScrollBarAsNeeded)
        self.view.setVerticalScrollBarPolicy(Qt.ScrollBarAsNeeded)
        self.view.setRenderHint(QPainter.SmoothPixmapTransform)
        self.view.setTransformationAnchor(QGraphicsView.NoAnchor)
        self.view.setResizeAnchor(QGraphicsView.NoAnchor)
        
        # 缩放控件
        self.zoom_layout = QHBoxLayout()
        self.zoom_layout.setSpacing(8)
        
        self.zoom_label = SubtitleLabel("缩放")
        self.zoom_slider = ToolTipSlider(Qt.Horizontal)
        self.zoom_slider.setRange(10, 400)
        self.zoom_slider.setValue(cfg.selectorWindowZoom.value)
        self.zoom_slider.setPageStep(10)
        self.zoom_slider.setSingleStep(1)
        self.zoom_slider.setTracking(True)
        self.zoom_slider.setFixedWidth(200)
        self.zoom_slider.valueChanged.connect(lambda v: self.zoom_slider.setToolTip(f"{v}%"))
        
        # 添加分辨率调整选项
        self.resize_check = CheckBox('调整尺寸', self)
        self.resize_check.setChecked(True)
        
        self.zoom_layout.addWidget(self.zoom_label)
        self.zoom_layout.addWidget(self.zoom_slider)
        self.zoom_layout.addWidget(self.resize_check)
        self.zoom_layout.addStretch()
        
        # 连接信号
        self.zoom_slider.valueChanged.connect(self._on_zoom_value_changed)
        
        # 添加工具栏布局
        self.toolbar_layout = QHBoxLayout()
        self.toolbar_layout.setSpacing(8)
        
        # 文件操作按钮
        # self.load_button = PushButton("打开图片", self, FIF.FOLDER)  # 注释掉行
        # self.load_clipboard_button = PushButton("加载图片", self, FIF.PASTE)  # 注释掉这行
        self.pixpin_button = PushButton("PixPin", self, FIF.CAMERA)
        self.insert_button = PushButton("插入图片", self, FIF.PHOTO)
        self.clear_button = PushButton("清除选择", self, FIF.DELETE)
        self.confirm_button = PrimaryPushButton("保存选区", self, FIF.SAVE)
        
        # 编辑操作按钮
        self.undo_button = PushButton("撤销", self, FIF.CANCEL)
        self.redo_button = PushButton("重做", self, FIF.RIGHT_ARROW)
        
        # 添加按钮到工具栏
        # self.toolbar_layout.addWidget(self.load_button)  # 注释掉这行
        # self.toolbar_layout.addWidget(self.load_clipboard_button)  # 注释掉这行
        self.toolbar_layout.addWidget(self.clear_button)
        self.toolbar_layout.addWidget(self.undo_button)
        self.toolbar_layout.addWidget(self.redo_button)
        self.toolbar_layout.addLayout(self.zoom_layout)
        self.toolbar_layout.addStretch()
        self.toolbar_layout.addWidget(self.pixpin_button)
        self.toolbar_layout.addWidget(self.insert_button)
        self.toolbar_layout.addWidget(self.confirm_button)
        
        # 添加控件到主布局
        self.layout.addLayout(self.toolbar_layout)
        self.layout.addWidget(self.view)
        
        # 连接信号
        # self.load_button.clicked.connect(self.load_image)  # 注释掉这行
        # self.load_clipboard_button.clicked.connect(self.load_image_from_clipboard)  # 注释掉这行
        self.pixpin_button.clicked.connect(self.launch_pixpin)
        self.insert_button.clicked.connect(self.insert_image)
        self.clear_button.clicked.connect(self.scene.clear_selection)
        self.confirm_button.clicked.connect(self.get_selected_regions)
        self.undo_button.clicked.connect(self.scene.undo)
        self.redo_button.clicked.connect(self.scene.redo)
        
        # 初始化时禁用撤销/重做按钮
        self.undo_button.setEnabled(False)
        self.redo_button.setEnabled(False)
        
        # 初始化时禁用保存选区按钮
        self.confirm_button.setEnabled(False)
        
        # 设置保存的缩放值
        self.zoom_slider.setValue(cfg.selectorWindowZoom.value)
        
        # 设置保存的调整尺寸状态
        self.resize_check.setChecked(cfg.selectorWindowResize.value)
        
        # 添加窗口关闭事件处理
        self.closeEvent = self.on_close
        
        # 连接复选框状态变化信号
        self.resize_check.stateChanged.connect(self._on_resize_check_changed)
        
        # 添加窗大小改变事件理
        self.resizeEvent = self.on_resize
        
        # 加载保存的设置
        self._load_saved_settings()
        
    def _on_zoom_value_changed(self, value):
        """处理缩放值改变"""
        if not self.current_pixmap:
            return
            
        # 更新配置
        cfg.selectorWindowZoom.value = value
        cfg.save()

        # 更新视图缩放
        transform = QTransform()
        transform.scale(value / 100.0, value / 100.0)
        self.view.setTransform(transform)
        
    def load_image(self):
        file_name, _ = QFileDialog.getOpenFileName(
            self, "选择图片", "", "图片文件 (*.png *.jpg *.bmp)")
        if file_name:
            # 先清空选区，再清空场景
            self.scene.clear_selection()
            self.scene.clear()
            
            self.current_pixmap = QPixmap(file_name)
            self.scene.addPixmap(self.current_pixmap)
            self.scene.setSceneRect(self.current_pixmap.rect())
            
            # 直接使用当前的缩放值
            current_zoom = self.zoom_slider.value()
            transform = QTransform()
            transform.scale(current_zoom / 100.0, current_zoom / 100.0)
            self.view.setTransform(transform)
            
            self.scene.set_has_image(True)
            self.update_confirm_button()
        else:
            self.scene.set_has_image(False)
            self.update_confirm_button()
            
    def _get_processed_selection(self):
        """处理并返回选中区域的图片，将透明背景转换为白色
        
        Returns:
            QPixmap | None: 处理后的图片，如果没有图片则返回 None
        """
        if not self.current_pixmap:
            return None
        
        # 如果没有选区或选区路径为空,返回整个图片
        if not self.scene.merged_path or self.scene.merged_path.isEmpty():
            result_image = self.current_pixmap.copy()
        else:
            # 获取选区路径
            path = self.scene.merged_path
            bounds = path.boundingRect()
            
            # 创建新的图片来绘制选区内容
            result_image = QPixmap(int(bounds.width()), int(bounds.height()))
            # 先将背景填充为白色
            result_image.fill(Qt.white)
            
            painter = QPainter(result_image)
            painter.setRenderHint(QPainter.Antialiasing)
            
            # 将路径移动到(0,0)位置
            painter.translate(-bounds.x(), -bounds.y())
            
            # 设置裁剪路径
            painter.setClipPath(path)
            
            # 绘制原图对应区域
            painter.drawPixmap(self.current_pixmap.rect(), self.current_pixmap)
            painter.end()
        
        # 创建一个新的白色背景图片
        final_image = QPixmap(result_image.size())
        final_image.fill(Qt.white)
        
        # 在白色背景上绘制结果图片
        painter = QPainter(final_image)
        painter.setRenderHint(QPainter.Antialiasing)
        painter.drawPixmap(0, 0, result_image)
        painter.end()
        
        # 根据选项决定是否应用缩放
        if self.resize_check.isChecked():
            scale = self.zoom_slider.value() / 100.0
            if scale != 1.0:
                new_width = int(final_image.width() * scale)
                new_height = int(final_image.height() * scale)
                final_image = final_image.scaled(
                    new_width, 
                    new_height,
                    Qt.KeepAspectRatio, 
                    Qt.SmoothTransformation
                )
            
        return final_image

    def insert_image(self):
        if not self.current_pixmap:  # 如果没有片,直接返回
            return
        
        result_image = self._get_processed_selection()
        if result_image:
            # 将 QPixmap 转换为字节数组
            byte_array = QByteArray()
            buffer = QBuffer(byte_array)
            buffer.open(QBuffer.WriteOnly)
            result_image.save(buffer, "BMP")  # 使用BMP格式
            buffer.close()
            
            # 获取字节数据
            data = byte_array.data()

            # 打开剪贴板
            win32clipboard.OpenClipboard()
            try:
                # 清空剪贴板
                win32clipboard.EmptyClipboard()
                # 设置剪贴板数据
                win32clipboard.SetClipboardData(win32clipboard.CF_DIB, data[14:])  # 跳过BMP文件头
            finally:
                # 确保剪贴板被关闭
                win32clipboard.CloseClipboard()

            # if cfg.bedEnabled.value:
            #     self.controller.picgo()
            g_vars.simulate_ctrl_v()
            if not cfg.autoPasteEnabled.value and cfg.dataWritePromptEnabled.value:
                g_vars.show_toast("数据已写入剪贴板需手动粘贴")

    def get_selected_regions(self):
        """保存选中的区域到文件"""
        if not self.current_pixmap:  # 如果没有图片,直接返回
            return
        
        result_image = self._get_processed_selection()
        if result_image:
            # 弹出保存文件话框
            file_name, _ = QFileDialog.getSaveFileName(
                self,
                "保存选区",
                "",
                "PNG图片 (*.png);;JPEG图片 (*.jpg);;所有文件 (*.*)"
            )
            
            if file_name:
                # 确保文件名有正确的扩展名
                if not file_name.lower().endswith(('.png', '.jpg', '.jpeg')):
                    file_name += '.png'
                
                # 保存图片
                result_image.save(file_name)
                
                # 显示成功消息
                from qfluentwidgets import InfoBar, InfoBarPosition
                InfoBar.success(
                    title='保存成功',
                    content=f"图片已保存至: {file_name}",
                    orient=Qt.Horizontal,
                    isClosable=True,
                    position=InfoBarPosition.TOP,
                    duration=2000,
                    parent=self
                )
        
    def update_confirm_button(self):
        """更新保存选区按钮状态"""
        # 只要有图片就启用保存按钮
        self.confirm_button.setEnabled(self.current_pixmap is not None)
        
    def _on_resize_check_changed(self, state):
        """处理复选框状态变化"""
        cfg.selectorWindowResize.value = bool(state)
        cfg.save()  # 使用cfg.save()
        
    def on_close(self, event):
        """窗口关闭时保存尺寸和位置"""
        # 保存窗口尺寸
        cfg.selectorWindowWidth.value = self.width()
        cfg.selectorWindowHeight.value = self.height()
        
        # 保存窗口位置
        cfg.selectorWindowX.value = self.x()
        cfg.selectorWindowY.value = self.y()
        
        # 保存配置
        cfg.save()
        event.accept()
        
    def on_resize(self, event):
        """处理窗口大小改变事件"""
        if self.isVisible():  # 只在窗口显示时保存尺寸
            cfg.selectorWindowWidth.value = self.width()
            cfg.selectorWindowHeight.value = self.height()
            cfg.save()  # 使用cfg.save()
        event.accept()
        
    def showEvent(self, event):
        """重写显示事件，设置窗口无焦点"""
        if sys.platform == 'win32':
            # Windows API 常量
            GWL_EXSTYLE = -20
            
            WS_EX_NOACTIVATE = 0x08000000

            # 取口句柄
            hwnd = ctypes.c_int(self.winId().__int__())
            
            # 获取当前窗口样式
            
            current_style = ctypes.windll.user32.GetWindowLongW(hwnd, GWL_EXSTYLE)
            
            # 检查是否已经设置了未激活样式
            if current_style & WS_EX_NOACTIVATE:
                return
            
            # 设置新的窗口样式
            ctypes.windll.user32.SetWindowLongW(
                hwnd,
                GWL_EXSTYLE,
                current_style | WS_EX_NOACTIVATE
            )
    
        super().showEvent(event)
        
    def _load_saved_settings(self):
        """加载保存的设置"""
        # 加载窗口尺寸
        self.resize(cfg.selectorWindowWidth.value, cfg.selectorWindowHeight.value)
        
        # 加载窗口位置
        self.move(cfg.selectorWindowX.value, cfg.selectorWindowY.value)
        
        # 加载缩放值
        self.zoom_slider.setValue(cfg.selectorWindowZoom.value)
        
        # 加载复选框状态
        self.resize_check.setChecked(cfg.selectorWindowResize.value)
        
    def launch_pixpin(self):
        """启动 PixPin 截图工具"""
        if not self.current_pixmap:  # 如果没有图片,直接返回
            return
        
        result_image = self._get_processed_selection()
        if result_image:
            # 将 QPixmap 转换为字节数组
            byte_array = QByteArray()
            buffer = QBuffer(byte_array)
            buffer.open(QBuffer.WriteOnly)
            result_image.save(buffer, "BMP")  # 使用BMP格式
            buffer.close()
            
            # 获取字节数据
            data = byte_array.data()

            # 打开剪贴板
            win32clipboard.OpenClipboard()
            try:
                # 清空剪贴板
                win32clipboard.EmptyClipboard()
                # 设置剪贴板数据
                win32clipboard.SetClipboardData(win32clipboard.CF_DIB, data[14:])  # 跳过BMP文件头
            finally:
                # 确保剪贴板被关闭
                win32clipboard.CloseClipboard()

            keyboard.send("ctrl+2")
            QTimer.singleShot(300, lambda: keyboard.send("space"))
            
            

    def load_image_from_clipboard(self):
        """从剪贴板加载图片"""
        clipboard = QApplication.clipboard()
        mime_data = clipboard.mimeData()
        
        if mime_data.hasImage():
            pixmap = QPixmap(clipboard.pixmap())
            if not pixmap.isNull():
                # 先清空选区，再清空场景
                self.scene.clear_selection()
                self.scene.clear()
                
                self.current_pixmap = pixmap
                self.scene.addPixmap(self.current_pixmap)
                self.scene.setSceneRect(self.current_pixmap.rect())
                
                # 应用当前缩放
                current_zoom = self.zoom_slider.value()
                transform = QTransform()
                transform.scale(current_zoom / 100.0, current_zoom / 100.0)
                self.view.setTransform(transform)
                
                self.scene.set_has_image(True)
                self.update_confirm_button()
                return True
            else:
                self._show_error("剪贴板中的图片无效")
                self.scene.set_has_image(False)
                self.update_confirm_button()
                return False
        else:
            self._show_error("剪贴板中没有图片")
            self.scene.set_has_image(False)
            self.update_confirm_button()
            return False
            
    def _show_error(self, message):
        """显示错误消息"""
        from qfluentwidgets import InfoBar, InfoBarPosition
        InfoBar.error(
            title='错误',
            content=message,
            orient=Qt.Horizontal,
            isClosable=True,
            position=InfoBarPosition.TOP,
            duration=2000,
            parent=self
        )

    def moveEvent(self, event):
        """处理窗口移动事件"""
        if self.isVisible():  # 只在窗口显示时保存位置
            cfg.selectorWindowX.value = self.x()
            cfg.selectorWindowY.value = self.y()
            cfg.save()
        event.accept()